package com.softer.wxzj.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.softer.wxzj.common.entity.CommonResult;
import com.softer.wxzj.common.entity.Page;
import com.softer.wxzj.common.enums.NumStrEnum;
import com.softer.wxzj.common.enums.ShiroResultEnum;
import com.softer.wxzj.common.error.CourseException;
import com.softer.wxzj.common.flow.enums.FlowStateEnum;
import com.softer.wxzj.common.flow.enums.FlowTypeEnum;
import com.softer.wxzj.common.flow.util.FlowAddAuditUtil;
import com.softer.wxzj.common.util.DepositUtil;
import com.softer.wxzj.common.util.StringUtils;
import com.softer.wxzj.common.util.UUIDUtil;
import com.softer.wxzj.entity.*;
import com.softer.wxzj.mapper.*;
import com.softer.wxzj.service.OrgBuildAuditService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * @author Gong Zhiyang
 * @date 2020/5/29
 */
@Service
public class OrgBuildAuditServiceImpl implements OrgBuildAuditService {
    @Autowired
    private OrgBuildAuditMapper buildAuditMapper;
    @Autowired
    private BaseBuildInfoMapper baseBuildInfoMapper;
    @Autowired
    private OrgRegionAuditMapper orgRegionAuditMapper;
    @Autowired
    private FileServiceImpl fileService;
    @Autowired
    private SysOperatorMapper sysOperatorMapper;
    @Autowired
    private FlowAddAuditUtil flowAddAuditUtil;
    @Autowired
    private OrgBuildAuditMapper orgBuildAuditMapper;
    @Autowired
    private BaseRegionInfoMapper baseRegionInfoMapper;

    /**
     * 查询绑定的自然幢列表
     *
     * @param page          分页实体
     * @param baseBuildInfo 查询实体
     * @return 自然幢列表
     */
    @Override
    public PageInfo<BaseBuildInfo> getOrgBuildAuditList(Page page, BaseBuildInfo baseBuildInfo) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        List<BaseBuildInfo> list = buildAuditMapper.getOrgBuildAuditList(baseBuildInfo);
        return new PageInfo<>(list);
    }

    /**
     * 查询小区下可以绑定的自然幢列表
     * （自己物业下已经保存的，审核中的，审核通过的不查询）
     *
     * @param regionId 小区ID
     * @param operNo   外网登录账号
     * @return 自然幢列表
     */
    @Override
    public List<BaseBuildInfo> getAddBuildList(String regionId, String operNo) {
        return buildAuditMapper.getAddBuildList(regionId, operNo);
    }

    /**
     * 删除绑定的自然幢（只有未提交审核的可以删除）
     *
     * @param orgBuildAuditId 绑定的自然幢ID
     * @return 删除结果
     */
    @Override
    public CommonResult deleteAudit(String orgBuildAuditId) {
        //校验当前状态
        String flowState = buildAuditMapper.getFlowState(orgBuildAuditId);
        if (!NumStrEnum.ZERO.getNum().equals(flowState)) {
            return CommonResult.ResponseResult(0, "当前状态禁止删除");
        }
        int num = buildAuditMapper.deleteAudit(orgBuildAuditId);
        return CommonResult.ResponseResult(num);
    }

    /**
     * 新增绑定的自然幢
     *
     * @param buildAddAudit 绑定的自然幢ID集合
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult addAudit(BuildAddAudit buildAddAudit) {
        List<String> list = buildAddAudit.getList();
        BaseBuildInfo baseBuildInfo = baseBuildInfoMapper.getInfoById(list.get(0));
        for (String buildId : list) {
            addBuildAudit(buildAddAudit.getOperNo(), baseBuildInfo.getRegionNo(), buildId);
        }
        return CommonResult.ResponseResult(1);
    }

    /**
     * 提交自然幢绑定审核
     *
     * @param orgRegionAudit 绑定的自然幢ID集合
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult submit(OrgRegionAudit orgRegionAudit) {
        List<String> list = orgRegionAudit.getBuildList();
        String regionId = buildAuditMapper.getRegionId(list.get(0));
        String uuid = UUIDUtil.getUUID();
        //新增审核记录
        addRegionAudit(orgRegionAudit.getOperNo(), regionId, orgRegionAudit.getApplicationReason(), uuid);
        //保存图片
        CommonResult commonResult = fileService.addFile(orgRegionAudit.getFileTypeList(), uuid);
        if (ShiroResultEnum.FAIL.getCode() == commonResult.getData()) {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), commonResult.getMessage());
        }
        //修改选择的自然幢的状态
        String buildAuditList = String.join(",", list);
        int num = buildAuditMapper.updateAuditState(buildAuditList, orgRegionAudit.getOperNo(), uuid, "1");
        // 查询登录账号
        SysOperator sysOperator = sysOperatorMapper.getOperInfoByOperNo(orgRegionAudit.getOperNo());
        //绑定审批流
        String initState = flowAddAuditUtil.initFlow(uuid, FlowTypeEnum.REGION_BINDING.getType(), orgRegionAudit.getOperNo());
        //当返回通过NumStrEnum.TWO.getNum()时 表明该记录不需要审核，直接更新到业务表
        if (FlowStateEnum.PASS.getState().equals(initState)) {
            //审核通过
            orgRegionAuditMapper.updateState("2", orgRegionAudit.getOperNo(), uuid);
            //修改相关数据
            orgRegionAudit.setRegionId(regionId);
            orgRegionAudit.setOperNo(sysOperator.getOperNo());
            changeRegionAndBuild(orgRegionAudit, buildAuditList, uuid, sysOperator.getCompanyId());
        }
        return CommonResult.ResponseResult(num);
    }

    /**
     * 区域管理审核通过修改相关表
     */
    @Override
    public void changeRegionAndBuild(OrgRegionAudit orgRegionAudit, String buildAuditList, String regionAuidtId, String companyId) {
        //将绑定的自然幢的其他所有绑定，修改为解绑
        buildAuditMapper.updateBuildAuditState(buildAuditList, orgRegionAudit.getOperNo());
        //对当前自然幢进行绑定
        buildAuditMapper.updateAuditState(buildAuditList, orgRegionAudit.getOperNo(), regionAuidtId, "2");
        //修改自然幢下的物业
        buildAuditMapper.updateBuildInfo(buildAuditList, companyId, orgRegionAudit.getOperNo());
        //修改小区下的物业
        int no = baseRegionInfoMapper.selectHaveOrg(orgRegionAudit.getRegionId(), companyId);
        if (no == 0) {
            buildAuditMapper.updateRegionInfo(orgRegionAudit.getRegionId(), companyId, orgRegionAudit.getOperNo());
        }
    }

    /**
     * 查询绑定的自然幢列表
     * 用于下拉列表
     *
     * @param baseBuildInfo 查询实体
     * @return 自然幢列表
     */
    @Override
    public List<BaseBuildInfo> getAllOrgBuildAuditList(BaseBuildInfo baseBuildInfo) {
        return buildAuditMapper.getAllOrgBuildAuditList(baseBuildInfo);
    }

    /**
     * 绑定审核查询列表
     *
     * @param page           分页实体
     * @param orgRegionAudit 查询实体
     * @return 结果
     */
    @Override
    public PageInfo<Map<String, String>> getOrgRegionAuditList(Page page, OrgRegionAudit orgRegionAudit) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        List<Map<String, String>> list = orgRegionAuditMapper.getOrgRegionAuditList(orgRegionAudit);
        return new PageInfo<>(list);
    }

    /**
     * 绑定审核记录列表
     *
     * @param page          分页实体
     * @param baseBuildInfo 查询实体
     * @return 结果
     */
    @Override
    public PageInfo<Map<String, String>> getOrgBuildInfoByOrgRegionId(Page page, BaseBuildInfo baseBuildInfo) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        List<Map<String, String>> list = orgRegionAuditMapper.getOrgBuildInfoByOrgRegionId(baseBuildInfo);
        return new PageInfo<>(list);
    }

    @Override
    public PageInfo<OrgBuildAudit> selectByRegionAuditId(Page page, OrgBuildAudit orgBuildAudit) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        List<OrgBuildAudit> list = orgBuildAuditMapper.selectByRegionAuditId(orgBuildAudit);
        for (OrgBuildAudit l : list) {
            if (StringUtils.isNotBlank(l.getSubRegionName())) {
                l.setBuildName(l.getBuildName() + "(" + l.getSubRegionName() + ")");
            }
        }
        int num = baseRegionInfoMapper.selectCount(orgBuildAudit.getRegionId());
        if (!list.isEmpty()) {
            list.get(0).setRegionNum(num);
        }
        return new PageInfo<>(list);
    }

    /**
     * 新增自然幢绑定
     *
     * @param operNo   登录账号
     * @param regionId 小区ID
     * @param buildId  自然幢ID
     */
    public void addBuildAudit(String operNo, String regionId, String buildId) {
        OrgBuildAudit orgBuildAudit = new OrgBuildAudit();
        orgBuildAudit.setOperNo(operNo);
        orgBuildAudit.setRegionId(regionId);
        orgBuildAudit.setBuildId(buildId);
        orgBuildAudit.setFlowState(NumStrEnum.ZERO.getNum());
        orgBuildAudit.setState(NumStrEnum.ONE.getNum());
        orgBuildAudit.setCreater(operNo);
        buildAuditMapper.add(orgBuildAudit);
    }

    /**
     * 新增提交审核记录
     *
     * @param operNo            登录账号
     * @param regionId          小区ID
     * @param applicationReason 申请理由
     * @param uuid              申请ID
     */
    public synchronized void addRegionAudit(String operNo, String regionId, String applicationReason, String uuid) {
        OrgRegionAudit orgRegionAudit = new OrgRegionAudit();
        orgRegionAudit.setId(uuid);
        orgRegionAudit.setRegionAuditNo(DepositUtil.getNo("z"));
        orgRegionAudit.setOperNo(operNo);
        orgRegionAudit.setRegionId(regionId);
        orgRegionAudit.setFlowState(NumStrEnum.ONE.getNum());
        orgRegionAudit.setApplicationReason(applicationReason);
        orgRegionAudit.setCreater(operNo);
        orgRegionAuditMapper.add(orgRegionAudit);
    }

}
